import * as cron from 'node-cron';
import { logger } from '../utils/logger';
import { CrawlerService } from '../services/CrawlerService';

export interface ScheduledTaskInfo {
  id: string;
  name: string;
  cronExpression: string;
  taskConfig: any;
  isActive: boolean;
  lastRun?: Date;
  nextRun?: Date;
}

export class SchedulerService {
  private tasks: Map<string, cron.ScheduledTask> = new Map();
  private taskInfos: Map<string, ScheduledTaskInfo> = new Map();
  private crawlerService: CrawlerService;

  constructor(crawlerService: CrawlerService) {
    this.crawlerService = crawlerService;
  }

  /**
   * 添加定时任务
   */
  addTask(task: ScheduledTaskInfo): boolean {
    try {
      if (this.tasks.has(task.id)) {
        logger.warn(`任务 ${task.id} 已存在，将被替换`);
        this.removeTask(task.id);
      }

      // 验证 cron 表达式
      if (!cron.validate(task.cronExpression)) {
        logger.error(`无效的 cron 表达式: ${task.cronExpression}`);
        return false;
      }

      const scheduledTask = cron.schedule(task.cronExpression, async () => {
        await this.executeTask(task);
      }, {
        scheduled: false, // 先不启动，等待手动启动
        timezone: 'Asia/Shanghai'
      });

      this.tasks.set(task.id, scheduledTask);
      this.taskInfos.set(task.id, task);

      if (task.isActive) {
        scheduledTask.start();
        logger.info(`定时任务 ${task.name} (${task.id}) 已启动`);
      }

      return true;
    } catch (error) {
      logger.error(`添加定时任务失败: ${error instanceof Error ? error.message : '未知错误'}`);
      return false;
    }
  }

  /**
   * 移除定时任务
   */
  removeTask(taskId: string): boolean {
    try {
      const task = this.tasks.get(taskId);
      if (task) {
        task.stop();
        // node-cron 的 ScheduledTask 没有 destroy 方法
        this.tasks.delete(taskId);
        this.taskInfos.delete(taskId);
        logger.info(`定时任务 ${taskId} 已移除`);
        return true;
      }
      return false;
    } catch (error) {
      logger.error(`移除定时任务失败: ${error instanceof Error ? error.message : '未知错误'}`);
      return false;
    }
  }

  /**
   * 启动任务
   */
  startTask(taskId: string): boolean {
    try {
      const task = this.tasks.get(taskId);
      if (task) {
        task.start();
        logger.info(`定时任务 ${taskId} 已启动`);
        return true;
      }
      logger.warn(`任务 ${taskId} 不存在`);
      return false;
    } catch (error) {
      logger.error(`启动定时任务失败: ${error instanceof Error ? error.message : '未知错误'}`);
      return false;
    }
  }

  /**
   * 停止任务
   */
  stopTask(taskId: string): boolean {
    try {
      const task = this.tasks.get(taskId);
      if (task) {
        task.stop();
        logger.info(`定时任务 ${taskId} 已停止`);
        return true;
      }
      logger.warn(`任务 ${taskId} 不存在`);
      return false;
    } catch (error) {
      logger.error(`停止定时任务失败: ${error instanceof Error ? error.message : '未知错误'}`);
      return false;
    }
  }

  /**
   * 获取所有任务状态
   */
  getAllTasks(): Array<{id: string, running: boolean}> {
    const result: Array<{id: string, running: boolean}> = [];
    
    for (const [id, task] of this.tasks.entries()) {
      // node-cron 的 ScheduledTask 没有 running 属性，我们从 taskInfos 获取状态
      const taskInfo = this.taskInfos.get(id);
      result.push({
        id,
        running: taskInfo?.isActive || false
      });
    }
    
    return result;
  }

  /**
   * 执行任务
   */
  private async executeTask(task: ScheduledTaskInfo): Promise<void> {
    try {
      logger.info(`开始执行定时任务: ${task.name} (${task.id})`);
      
      // 更新最后运行时间
      task.lastRun = new Date();
      
      // 执行爬虫任务
      await this.crawlerService.executeCrawlerTask(task.taskConfig.taskId || task.id);
      
      logger.info(`定时任务执行完成: ${task.name} (${task.id})`);
    } catch (error) {
      logger.error(`定时任务执行失败: ${task.name} (${task.id})`, error);
    }
  }

  /**
   * 停止所有任务
   */
  stopAll(): void {
    try {
      for (const [id, task] of this.tasks.entries()) {
        task.stop();
        logger.info(`定时任务 ${id} 已停止`);
      }
      logger.info('所有定时任务已停止');
    } catch (error) {
      logger.error(`停止所有定时任务失败: ${error instanceof Error ? error.message : '未知错误'}`);
    }
  }

  /**
   * 销毁调度器
   */
  destroy(): void {
    try {
      for (const [id, task] of this.tasks.entries()) {
        task.stop();
        // node-cron 的 ScheduledTask 没有 destroy 方法
      }
      this.tasks.clear();
      logger.info('调度器已销毁');
    } catch (error) {
      logger.error(`销毁调度器失败: ${error instanceof Error ? error.message : '未知错误'}`);
    }
  }

  /**
   * 获取下次运行时间
   */
  getNextRunTime(cronExpression: string): Date | null {
    try {
      if (!cron.validate(cronExpression)) {
        return null;
      }
      
      // 这里可以使用 cron-parser 库来计算下次运行时间
      // 暂时返回一个小时后的时间作为示例
      const nextRun = new Date();
      nextRun.setHours(nextRun.getHours() + 1);
      return nextRun;
    } catch (error) {
      logger.error(`计算下次运行时间失败: ${error instanceof Error ? error.message : '未知错误'}`);
      return null;
    }
  }
}
